home *** CD-ROM | disk | FTP | other *** search
- #ifdef SYSTEM_WIN32
- #define WIN32_LEAN_AND_MEAN
- #include <windows.h>
- #include <malloc.h>
- #endif
-
- #ifdef HAVE_CONFIG_H
- #include "config.h"
- #endif
-
- #include "cmdlib.h"
- #include "messages.h"
- #include "log.h"
- #include "threads.h"
- #include "blockmem.h"
-
- #ifdef SYSTEM_POSIX
- #ifdef HAVE_SYS_TIME_H
- #include <sys/time.h>
- #endif
- #ifdef HAVE_SYS_RESOURCE_H
- #include <sys/resource.h>
- #include <pthread.h>
- #endif
- #ifdef HAVE_PTHREAD_H
- #include <pthread.h>
- #endif
- #endif
-
- #include "hlassert.h"
-
- q_threadpriority g_threadpriority = DEFAULT_THREAD_PRIORITY;
-
- #define THREADTIMES_SIZE 100
- #define THREADTIMES_SIZEf (float)(THREADTIMES_SIZE)
-
- static int dispatch = 0;
- static int workcount = 0;
- static int oldf = 0;
- static bool pacifier = false;
- static bool threaded = false;
- static double threadstart = 0;
- static double threadtimes[THREADTIMES_SIZE];
-
- int GetThreadWork()
- {
- int r, f, i;
- double ct, finish, finish2, finish3;
-
- ThreadLock();
-
- if (dispatch == 0)
- {
- oldf = 0;
- }
-
- if (dispatch > workcount)
- {
- Developer(DEVELOPER_LEVEL_ERROR, "dispatch > workcount!!!\n");
- ThreadUnlock();
- return -1;
- }
- if (dispatch == workcount)
- {
- Developer(DEVELOPER_LEVEL_MESSAGE, "dispatch == workcount, work is complete\n");
- ThreadUnlock();
- return -1;
- }
- if (dispatch < 0)
- {
- Developer(DEVELOPER_LEVEL_ERROR, "negative dispatch!!!\n");
- ThreadUnlock();
- return -1;
- }
-
- f = THREADTIMES_SIZE * dispatch / workcount;
- if (pacifier)
- {
- printf("\r%6d /%6d", dispatch, workcount);
- #ifdef ZHLT_PROGRESSFILE // AJM
- if (g_progressfile)
- {
-
-
- }
- #endif
-
- if (f != oldf)
- {
- ct = I_FloatTime();
- /* Fill in current time for threadtimes record */
- for (i = oldf; i <= f; i++)
- {
- if (threadtimes[i] < 1)
- {
- threadtimes[i] = ct;
- }
- }
- oldf = f;
-
- if (f > 10)
- {
- finish = (ct - threadtimes[0]) * (THREADTIMES_SIZEf - f) / f;
- finish2 = 10.0 * (ct - threadtimes[f - 10]) * (THREADTIMES_SIZEf - f) / THREADTIMES_SIZEf;
- finish3 = THREADTIMES_SIZEf * (ct - threadtimes[f - 1]) * (THREADTIMES_SIZEf - f) / THREADTIMES_SIZEf;
-
- if (finish > 1.0)
- {
- printf(" (%d%%: est. time to completion %ld/%ld/%ld secs) ", f, (long)(finish), (long)(finish2),
- (long)(finish3));
- #ifdef ZHLT_PROGRESSFILE // AJM
- if (g_progressfile)
- {
-
-
- }
- #endif
- }
- else
- {
- printf(" (%d%%: est. time to completion <1 sec) ", f);
-
- #ifdef ZHLT_PROGRESSFILE // AJM
- if (g_progressfile)
- {
-
-
- }
- #endif
- }
- }
- }
- }
- else
- {
- if (f != oldf)
- {
- oldf = f;
- switch (f)
- {
- case 10:
- case 20:
- case 30:
- case 40:
- case 50:
- case 60:
- case 70:
- case 80:
- case 90:
- case 100:
- /*
- case 5:
- case 15:
- case 25:
- case 35:
- case 45:
- case 55:
- case 65:
- case 75:
- case 85:
- case 95:
- */
- printf("%d%%...", f);
- default:
- break;
- }
- }
- }
-
- r = dispatch;
- dispatch++;
-
- ThreadUnlock();
- return r;
- }
-
- q_threadfunction workfunction;
-
- #ifdef SYSTEM_WIN32
- #pragma warning(push)
- #pragma warning(disable: 4100) // unreferenced formal parameter
- #endif
- static void ThreadWorkerFunction(int unused)
- {
- int work;
-
- while ((work = GetThreadWork()) != -1)
- {
- workfunction(work);
- }
- }
-
- #ifdef SYSTEM_WIN32
- #pragma warning(pop)
- #endif
-
- void RunThreadsOnIndividual(int workcnt, bool showpacifier, q_threadfunction func)
- {
- workfunction = func;
- RunThreadsOn(workcnt, showpacifier, ThreadWorkerFunction);
- }
-
- #ifndef SINGLE_THREADED
-
- /*====================
- | Begin SYSTEM_WIN32
- =*/
- #ifdef SYSTEM_WIN32
-
- #define USED
- #include <windows.h>
-
- int g_numthreads = DEFAULT_NUMTHREADS;
- static CRITICAL_SECTION crit;
- static int enter;
-
- void ThreadSetPriority(q_threadpriority type)
- {
- int val;
-
- g_threadpriority = type;
-
- switch (g_threadpriority)
- {
- case eThreadPriorityLow:
- val = IDLE_PRIORITY_CLASS;
- break;
-
- case eThreadPriorityHigh:
- val = HIGH_PRIORITY_CLASS;
- break;
-
- case eThreadPriorityNormal:
- default:
- val = NORMAL_PRIORITY_CLASS;
- break;
- }
-
- SetPriorityClass(GetCurrentProcess(), val);
- }
-
- #if 0
- static void AdjustPriority(HANDLE hThread)
- {
- int val;
-
- switch (g_threadpriority)
- {
- case eThreadPriorityLow:
- val = THREAD_PRIORITY_HIGHEST;
- break;
-
- case eThreadPriorityHigh:
- val = THREAD_PRIORITY_LOWEST;
- break;
-
- case eThreadPriorityNormal:
- default:
- val = THREAD_PRIORITY_NORMAL;
- break;
- }
- SetThreadPriority(hThread, val);
- }
- #endif
-
- void ThreadSetDefault()
- {
- SYSTEM_INFO info;
-
- if (g_numthreads == -1) // not set manually
- {
- GetSystemInfo(&info);
- g_numthreads = info.dwNumberOfProcessors;
- if (g_numthreads < 1 || g_numthreads > 32)
- {
- g_numthreads = 1;
- }
- }
- }
-
- void ThreadLock()
- {
- if (!threaded)
- {
- return;
- }
- EnterCriticalSection(&crit);
- if (enter)
- {
- Warning("Recursive ThreadLock\n");
- }
- enter++;
- }
-
- void ThreadUnlock()
- {
- if (!threaded)
- {
- return;
- }
- if (!enter)
- {
- Error("ThreadUnlock without lock\n");
- }
- enter--;
- LeaveCriticalSection(&crit);
- }
-
- q_threadfunction q_entry;
-
- static DWORD WINAPI ThreadEntryStub(LPVOID pParam)
- {
- q_entry((int)pParam);
- return 0;
- }
-
- void threads_InitCrit()
- {
- InitializeCriticalSection(&crit);
- threaded = true;
- }
-
- void threads_UninitCrit()
- {
- DeleteCriticalSection(&crit);
- }
-
- void RunThreadsOn(int workcnt, bool showpacifier, q_threadfunction func)
- {
- DWORD threadid[MAX_THREADS];
- HANDLE threadhandle[MAX_THREADS];
- int i;
- double start, end;
-
- threadstart = I_FloatTime();
- start = threadstart;
- for (i = 0; i < THREADTIMES_SIZE; i++)
- {
- threadtimes[i] = 0;
- }
- dispatch = 0;
- workcount = workcnt;
- oldf = -1;
- pacifier = showpacifier;
- threaded = true;
- q_entry = func;
-
- if (workcount < dispatch)
- {
- Developer(DEVELOPER_LEVEL_ERROR, "RunThreadsOn: Workcount(%i) < dispatch(%i)\n", workcount, dispatch);
- }
- hlassume(workcount >= dispatch, assume_BadWorkcount);
-
- //
- // Create all the threads (suspended)
- //
- threads_InitCrit();
- for (i = 0; i < g_numthreads; i++)
- {
- HANDLE hThread = CreateThread(NULL,
- 0,
- (LPTHREAD_START_ROUTINE) ThreadEntryStub,
- (LPVOID) i,
- CREATE_SUSPENDED,
- &threadid[i]);
-
- if (hThread != NULL)
- {
- threadhandle[i] = hThread;
- }
- else
- {
- LPVOID lpMsgBuf;
-
- FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
- FORMAT_MESSAGE_FROM_SYSTEM |
- FORMAT_MESSAGE_IGNORE_INSERTS, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
- (LPTSTR) & lpMsgBuf, 0, NULL);
- // Process any inserts in lpMsgBuf.
- // ...
- // Display the string.
- Developer(DEVELOPER_LEVEL_ERROR, "CreateThread #%d [%08X] failed : %s\n", i, threadhandle[i], lpMsgBuf);
- Fatal(assume_THREAD_ERROR, "Unable to create thread #%d", i);
- // Free the buffer.
- LocalFree(lpMsgBuf);
- }
- }
- CheckFatal();
-
- // Start all the threads
- for (i = 0; i < g_numthreads; i++)
- {
- if (ResumeThread(threadhandle[i]) == 0xFFFFFFFF)
- {
- LPVOID lpMsgBuf;
-
- FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
- FORMAT_MESSAGE_FROM_SYSTEM |
- FORMAT_MESSAGE_IGNORE_INSERTS, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
- (LPTSTR) & lpMsgBuf, 0, NULL);
- // Process any inserts in lpMsgBuf.
- // ...
- // Display the string.
- Developer(DEVELOPER_LEVEL_ERROR, "ResumeThread #%d [%08X] failed : %s\n", i, threadhandle[i], lpMsgBuf);
- Fatal(assume_THREAD_ERROR, "Unable to start thread #%d", i);
- // Free the buffer.
- LocalFree(lpMsgBuf);
- }
- }
- CheckFatal();
-
- // Wait for threads to complete
- for (i = 0; i < g_numthreads; i++)
- {
- Developer(DEVELOPER_LEVEL_MESSAGE, "WaitForSingleObject on thread #%d [%08X]\n", i, threadhandle[i]);
- WaitForSingleObject(threadhandle[i], INFINITE);
- }
- threads_UninitCrit();
-
- q_entry = NULL;
- threaded = false;
- end = I_FloatTime();
- if (pacifier)
- {
- printf("\r%60s\r", "");
- }
- Log(" (%.2f seconds)\n", end - start);
- }
-
- #endif
-
- /*=
- | End SYSTEM_WIN32
- =====================*/
-
- /*====================
- | Begin SYSTEM_POSIX
- =*/
- #ifdef SYSTEM_POSIX
-
- #define USED
-
- int g_numthreads = DEFAULT_NUMTHREADS;
-
- void ThreadSetPriority(q_threadpriority type)
- {
- int val;
-
- g_threadpriority = type;
-
- // Currently in Linux land users are incapable of raising the priority level of their processes
- // Unless you are root -high is useless . . .
- switch (g_threadpriority)
- {
- case eThreadPriorityLow:
- val = PRIO_MAX;
- break;
-
- case eThreadPriorityHigh:
- val = PRIO_MIN;
- break;
-
- case eThreadPriorityNormal:
- default:
- val = 0;
- break;
- }
- setpriority(PRIO_PROCESS, 0, val);
- }
-
- void ThreadSetDefault()
- {
- if (g_numthreads == -1)
- {
- g_numthreads = 1;
- }
- }
-
- typedef void* pthread_addr_t;
- pthread_mutex_t* my_mutex;
-
- void ThreadLock()
- {
- if (my_mutex)
- {
- pthread_mutex_lock(my_mutex);
- }
- }
-
- void ThreadUnlock()
- {
- if (my_mutex)
- {
- pthread_mutex_unlock(my_mutex);
- }
- }
-
- q_threadfunction q_entry;
-
- static void* CDECL ThreadEntryStub(void* pParam)
- {
- q_entry((int)pParam);
- return NULL;
- }
-
- void threads_InitCrit()
- {
- pthread_mutexattr_t mattrib;
-
- if (!my_mutex)
- {
- my_mutex = (pthread_mutex_t*)Alloc(sizeof(*my_mutex));
- if (pthread_mutexattr_init(&mattrib) == -1)
- {
- Error("pthread_mutex_attr_init failed");
- }
- if (pthread_mutex_init(my_mutex, &mattrib) == -1)
- {
- Error("pthread_mutex_init failed");
- }
- }
- }
-
- void threads_UninitCrit()
- {
- Free(my_mutex);
- my_mutex = NULL;
- }
-
- /*
- * =============
- * RunThreadsOn
- * =============
- */
- void RunThreadsOn(int workcnt, bool showpacifier, q_threadfunction func)
- {
- int i;
- pthread_t work_threads[MAX_THREADS];
- pthread_addr_t status;
- pthread_attr_t attrib;
- double start, end;
-
- threadstart = I_FloatTime();
- start = threadstart;
- for (i = 0; i < THREADTIMES_SIZE; i++)
- {
- threadtimes[i] = 0;
- }
-
- dispatch = 0;
- workcount = workcnt;
- oldf = -1;
- pacifier = showpacifier;
- threaded = true;
- q_entry = func;
-
- if (pacifier)
- {
- setbuf(stdout, NULL);
- }
-
- threads_InitCrit();
-
- if (pthread_attr_init(&attrib) == -1)
- {
- Error("pthread_attr_init failed");
- }
- #ifdef _POSIX_THREAD_ATTR_STACKSIZE
- if (pthread_attr_setstacksize(&attrib, 0x400000) == -1)
- {
- Error("pthread_attr_setstacksize failed");
- }
- #endif
-
- for (i = 0; i < g_numthreads; i++)
- {
- if (pthread_create(&work_threads[i], &attrib, ThreadEntryStub, (void*)i) == -1)
- {
- Error("pthread_create failed");
- }
- }
-
- for (i = 0; i < g_numthreads; i++)
- {
- if (pthread_join(work_threads[i], &status) == -1)
- {
- Error("pthread_join failed");
- }
- }
-
- threads_UninitCrit();
-
- q_entry = NULL;
- threaded = false;
-
- end = I_FloatTime();
- if (pacifier)
- {
- printf("\r%60s\r", "");
- }
-
- Log(" (%.2f seconds)\n", end - start);
- }
-
- #endif /*SYSTEM_POSIX */
-
- /*=
- | End SYSTEM_POSIX
- =====================*/
-
- #endif /*SINGLE_THREADED */
-
- /*====================
- | Begin SINGLE_THREADED
- =*/
- #ifdef SINGLE_THREADED
-
- int g_numthreads = 1;
-
- void ThreadSetPriority(q_threadpriority type)
- {
- }
-
- void threads_InitCrit()
- {
- }
-
- void threads_UninitCrit()
- {
- }
-
- void ThreadSetDefault()
- {
- g_numthreads = 1;
- }
-
- void ThreadLock()
- {
- }
-
- void ThreadUnlock()
- {
- }
-
- void RunThreadsOn(int workcnt, bool showpacifier, q_threadfunction func)
- {
- int i;
- double start, end;
-
- dispatch = 0;
- workcount = workcnt;
- oldf = -1;
- pacifier = showpacifier;
- threadstart = I_FloatTime();
- start = threadstart;
- for (i = 0; i < THREADTIMES_SIZE; i++)
- {
- threadtimes[i] = 0.0;
- }
-
- if (pacifier)
- {
- setbuf(stdout, NULL);
- }
- func(0);
-
- end = I_FloatTime();
-
- if (pacifier)
- {
- printf("\r%60s\r", "");
- }
-
- Log(" (%.2f seconds)\n", end - start);
- }
-
- #endif
-
- /*=
- | End SINGLE_THREADED
- =====================*/
-